.TITLE DDDRV .IDENT /03.02/ ; ; Copyright (c) 1995-1999 by Mentec, Inc., U.S.A. ; All rights reserved ; ; ; THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED ; OR COPIED ONLY IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE. ; ; ; M. B. GROSSMAN 10/15/78 ; ; P. J. CARR ; J. GALLANT ; ; MODIFIED BY: 15-AUG-86 3.02 ; ; G. MARIGOWDA GM001 -- CONVERT TO USE EXEC VECTORING ; ; ; TU58 TAPE CARTRIDGE DRIVER ; ; THIS DRIVER INTERFACES WITH THE TU58 VIA A DL11 AT 9600 BAUD. ; COMMANDS, DATA AND DEVICE STATUS ARE FORMATTED INTO STRUCTURED ; PACKETS OF BYTES IN ACCORDANCE WITH RADIAL SERIAL PROTOCOL. ; ; MACRO LIBRARY CALLS ; .MCALL HWDDF$,PKTDF$,QIOSY$,SCBDF$ QIOSY$ SCBDF$ ,,SYSDEF HWDDF$ ;DEFINE HARDWARE REGISTERS PKTDF$ ;DEFINE I/O PACKET OFFSETS ; ; EQUATED SYMBOLS ; RTRY= 2 ;RETRY COUNT DDNUM= 6 ;NUMBER OF REGISTERS TO LOG ON ERROR ; ; TU58 RADIAL SERIAL PROTOCOL SYMBOLS ; ; INSTRUCTION SET ; READ= 2 ;READ INSTRUCTION WRITE= 3 ;WRITE INSTRUCTION POSIT= 5 ;POISITION INSTRUCTION -USER MODE DIAG. DIAG= 7 ;DIAGONOSE INSTRUCTION -USER MODE DIAG. TYPU58= 12 ;OPCODE TO CHECK FOR OLD OR NEW TU58 ; ; FLAGS ; DATA= 1 ;DATA FLAG CNTL= 2 ;CONTROL FLAG INIT= 4 ;INITIALIZE FLAG CONT= 20 ;CONTINUE FLAG END= 2 ;END FLAG ; ; DL11 INTERFACE OFFSET SYMBOLS ; DDRCS= 0 ;RECEIVE CONTROL STATUS REGISTER DDRBF= 2 ;RECEIVE BUFFER REGISTER DDXCS= 4 ;TRANSMITTER CONTROL STATUS REGISTER DDXBF= 6 ;TRANSMITTER BUFFER REGISTER ; ; DL11 BIT ASSIGNMENTS ; RDONE= 200 ;RECEIVER DONE RIE= 100 ;RECEIVER INTERRUPT ENABLE ERR= 100000 ;RECEIVER DATA ERROR TRDY= 200 ;TRANSMITTER READY TIE= 100 ;TRANSMITTER INTERRUPT ENABLE BRK= 1 ;TRANSMIT BREAK ; ; LOCAL BIT ASSIGNMENTS ; FLCTL = 10 ;FLOW CONTROL BIT IN SWITCH BYTE OF ;COMMAND PACKET (BIT 3) NTU58 = 1 ;NEW TU58 MICROCODE CHKDON = 2 ;TU58 TYPE CHECK DONE TU58C = 10 ;TU58 IS SENDING CONTINUE TRNACK = 20 ;TRANSMITTING THE ACK CHARACTER ; ; LOCAL DATA ; WORD1: .BLKW T$$U58 ;STORAGE FOR LAST THREE WORDS THAT ARE WORD2: .BLKW T$$U58 ;TO GO IN ERROR PACKET WORD3: .BLKW T$$U58 ; ; ; MAKE GTPKT$ A LOCAL MACRO ; .MACRO GTPKT$ DEV,NCTRLR,ADDR,UCBSV,SUC CALL @GTPKT .IF B BCC 65535$ RETURN 65535$: .IFF BCS ADDR .ENDC .IF B $$$=0 .IF B .IF EQ $$$ MOV R5,S.OWN(R4) .ENDC .ENDC .IFF .IF GT NCTRLR-1 MOV R5,UCBSV(R3) .IFF MOV R5,UCBSV .ENDC .ENDC .ENDM ; ; EXECUTIVE ENTRY POINT VECTOR TABLE ; EXEVEC: .WORD 0 ;FLAG FOR VECTOR NOT YET FILLED ALOCB: .WORD $ALOCB BLKCK: .WORD $BLKCK DEACB: .WORD $DEACB DTOER: .WORD $DTOER DVERR: .WORD $DVERR ERRSQ: .WORD $ERRSQ FORK: .WORD $FORK GTBYT: .WORD $GTBYT GTPKT: .WORD $GTPKT IODON: .WORD $IODON PTBYT: .WORD $PTBYT VOLVD: .WORD $VOLVD ; KISR6: .WORD KISAR6 ; EXEVCL=<<<.-EXEVEC>/2>-1> ; ;DRIVER DISPATCH TABLE ; DDT$ DD,T$$U58,,,,NEW ;2 INT. ENTRY PTS ; ; PROGRAM SEQUENCE CONTROL ; ; PROGRAM FLOW IS CONTROLLED BY A POINTER TO A TABLE OF ; ADDRESSES. THIS SEQUENCE CREATES AND DECODES THE RADIAL ; SERIAL PACKET INFORMATION. THE ACTUAL USER DATA IS ; TRANSFERRED WITHIN THE INTERRUPT SERVICE ROUTINE (ISR). ; THIS METHOD PERMITS US TO WAIT FOR INTERRUPTS WITHOUT ; HAVING TO PRESERVE ANY PROCESSOR REGISTERS (INCLUDING THE ; STACK). REPETITIVE SECTIONS OF CODE CAN BE EXECUTED A ; NUMBER OF TIMES WITHOUT LOOP COUNTERS. THIS METHOD ALSO ; DECREASES PROGRAM SIZE BY ALLOWING US TO USE BRANCHES ; RATHER THAN JSR'S. ; ; THE POINTER (LOCATION RADD) IS INCREMENTED VIA THE CODE ; IN RTBK (RETURN BACK). RTBK THEN SHIFTS CONTROL TO THE ; ADDRESS POINTED TO BY RADD. RTBK IS CALLED BY RMSG/SMSG OR ; THE INTERRUPT SERVICE ROUTINE WHENEVER THE DL11 IS READY ; TO PERFORM THE NEXT NON-DATA TRANSFER OPERATION. ; ; THE MODIFIED RADIAL SERIAL PROTOCOL ALGORITHM IS THE FOLLOWING: ; ; ISSUE A COMMAND TO THE TU58 WITH THE OPCODE 12 AND THE FLOW ; CONTROL BIT SET. RECEIVE THE FIRST BYTE OF THE TU58'S RESPONSE. ; IF IT'S A '1', IT IS AN OLD TU58. THE '1' IS THE FLAG FOR A DATA ; PACKET. IF THE RESPONSE IS A '2', IT IS A NEW TU58. THE '2' IS THE ; FLAG FOR AN END PACKET. FLUSH THE REST OF THE TU58'S RESPONSE BY ; SENDING THE TU58 AN INIT COMMAND. THE MEMORY LOCATION FLGTYP WILL ; HAVE BIT 0 SET FOR THE NEW TU58 AND BIT 0 WILL BE CLEARED FOR AN ; OLD TU58. ; ; THE COMMAND PACKET THAT AUTOCONFIGURES THE TU58 LOOKS AS FOLLOWS: ; ; BYTE BYTE CONTENTS ; ---- --------------- ; 0 FLAG - 2 ; 1 BYTE COUNT 12 ; 2 OPCODE 12 ; 3 MODIFIER 0 ; 4 UNIT # ; 5 SWITCHES 10 (FLOW CONTROL BIT SET - BIT 3) ; 6 SEQUENCE # 0 ; 7 SEQUENCE # 0 ; 8 BYTE COUNT 0 ; 9 BYTE COUNT 0 ; 10 BLOCK # 0 ; 11 BLOCK # 0 ; 12 CHECK SUM-LOW ; 13 CHECK SUM-HIGH ; ; ; CTAB- COMMAND PACKET SEQUENCE ; ; CONE IS THE ADDRESS RETURNED TO WHEN THE DL11 IS READY TO ; SEND THE FIRST BYTE OF THE 14. BYTE COMMAND PACKET. CTWO ; IS THE ADDRESS RETURNED TO WHEN READY FOR THE SECOND BYTE, ; ETC. CFIF IS EXECUTED AFTER ALL BYTES IN THE COMMAND PACKET ; ARE SENT. ; CTAB: .WORD CHALF,CONE,CTWO,CTHR,CFOUA,CFOUB,CFIV,CSIX,CSEV .WORD CEIG,CNIN,CTEN,CELE,CTWE,CTHI,CFOR,CFIF ; ; ITAB- INITIALIZATION SEQUENCE ; ITAB: .WORD IONE,ITWOA,ITWOB,ITWOC,ITWOD,ITWOE,ITHR,IFOU,IFIV,ISIX ;INIT. SEQ. ; ; TTAB- TRANSMIT DATA SEQUENCE ; TTAB: .WORD TONE,TTWO,TTHR,TFOU,TFOUA,TFIV,TSIX ; ; RTAB- RECEIVE DATA SEQUENCE ; RTAB: .WORD RONE,RTWO,RTHR,RFOU ;INCOMING (READ) DATA PACKET ADDRESSES ; ; ETAB- END PACKET DECODE SEQUENCE ; ETAB: .WORD EONE,ETWO,ETHR,EFOU,EFIV,ESIX,ESEV ;READ END PACKET .WORD EEIG,ENIN,ETEN,EELE,ETWE,ETHI ;FROM TU58 ; ; TYPTAB - DETERMINE TYPE OF TU58 ; TYPTAB: .WORD CONE,CTWO,TYPTHR,CFOUB,CFIV,TYPSIX,TYPSEV,TYPSEV .WORD TYPSEV,TYPSEV,TYPSEV,TYPSEV,CTHI,CFOR,TYPFIF .WORD TYPSXT,TYPSXT,TYPSXT,TYPSXT,TYPSXT,TYPSXT,TYPSXT,TYPSXT .WORD TYPSXT,TYPSXT,TYPSXT,TYPSXT,TYPSXT,TYPSVT ; ; CONTROLLER IMPURE DATA TABLES (INDEXED BY CONTROLLER NUMBER) ; RDAT: .BLKW T$$U58 ;RECEIVED DATA RADD: .BLKW T$$U58 ;RETURN ADDRESS POINTER DBUF: .BLKW T$$U58 ;DL11 BUFFER ADDRESS CKSM1: .BLKW T$$U58 ;CHECKSUM STORAGE-1ST WORD ;ALSO TEMPORARY DRIVER STORAGE CKSM2: .BLKW T$$U58 ;CHECKSUM STORAGE-2ND WORD ;ALSO TEMPORARY DRIVER STORAGE FLAG: .BLKW T$$U58 ;LOW BYTE-BYTE COUNT ;HIGH BYTE-SEND/REC. FLAG WCNT: .BLKW T$$U58 ;BYTES LEFT TO BE WRITTEN ;ALSO USED FOR RETURN ADDRESS ;DURING IOPKT SUBROUTINE ;ALSO USED FOR INITIALIZATION RETRY COUNT FLGTYP: .BLKW T$$U58 ;BIT 0 - 0 OLD TU58 ; 1 NEW TU58 ;BIT 1 - 0 NOT COMPLETED TU58 TYPE CHECK ; 1 COMPLETED TU58 TYPE CHECK ;BIT 3 - 0 TU58 NOT SENDING CONTINUE ; - 1 TU58 IS SENDING CONTINUE ;BIT 4 - 0 NOT TRANSMITTING THE ACK CHAR ; - 1 TRANSMITTING THE ACK CHAR ;+ ; **-DDINI- TU58 TAPE CARTRIDGE INITIATOR ; ; THIS ROUTINE IS ENTERED FROM THE QUEUE I/O DIRECTIVE WHEN AN ; I/O REQUEST IS QUEUED AND AT THE END OF A PREVIOUS I/O OPERATION ; TO PROPAGATE THE EXECUTION OF THE DRIVER. IF THE SPECIFIED ; CONTROLLER IS NOT BUSY, THEN AN ATTEMPT IS MADE TO DEQUEUE THE ; NEXT I/O REQUEST. ELSE A RETURN TO THE CALLER IS EXECUTED. IF ; THE DEQUEUE ATTEMPT IS SUCCESSFUL, THEN THE NEXT I/O OPERATION ; IS INITIATED. A RETURN TO THE CALLER IS THEN EXECUTED. ; ; INPUT: ; ; R5 = ADDRESS OF THE UCB OF THE CONTROLLER TO BE INITIATED ; ; OUTPUT: ; ; IF THE SPECIFIED CONTROLLER IS NOT BUSY AND AN I/O REQUEST ; IS WAITING TO BE PROCESSED, THEN THE REQUEST IS DEQUEUED ; AND THE DRIVER INITIATES THE REQUESTED I/O FUNCTION ;- .ENABL LSB DDINI: GTPKT$ DD ;GET NEXT I/O PACKET TO PROCESS ; ; THE FOLLOWING ARGUMENTS ARE RETURNED BY $GTPKT: ; ; R1=ADDRESS OF THE I/O REQUEST PACKET. ; R2=PHYSICAL UNIT NUMBER. ; R3=CONTROLLER INDEX. ; R4=ADDRESS OF THE STATUS CONTROL BLOCK. ; R5=ADDRESS OF THE UCB OF THE CONTROLLER TO BE INITIATED. ; ; TU58 TAPE CARTRIDGE DRIVE I/O REQUEST PACKET FORMAT: ; ; WD. 00 -- I/O QUEUE THREAD WORD. ; WD. 01 -- REQUEST PRIORITY, EVENT FLAG NUMBER. ; WD. 02 -- ADDRESS OF THE TCB OF THE REQUESTOR TASK. ; WD. 03 -- POINTER TO 2ND LUN WORD IN REQUESTOR TASK HEADER. ; WD. 04 -- CONTENTS OF 1ST LUN WORD IN REQUESTOR TASK HEADER. ; WD. 05 -- I/O FUNCTION CODE (IO.RLB, IO.WLB, IO.DGN, IO.BLS) ; WD. 06 -- VIRTUAL ADDRESS OF I/O STATUS BLOCK. ; WD. 07 -- RELOCATION BIAS OF I/O STATUS BLOCK. ; WD. 10 -- I/O STATUS BLOCK ADDRESS ; WD. 11 -- VIRTUAL ADDRESS OF AST SERVICE ROUTINE ; WD. 12 -- RELOCATION BIAS OF DATA BUFFER ; WD. 13 -- BUFFER ADDRESS OF I/O TRANSFER ; WD. 14 -- NUMBER OF BYTES TO TRANSFER ; WD. 15 -- NOT USED ; WD. 16 -- LOW BYTE MUST BE ZERO, HIGH BYTE NOT USED ; WD. 17 -- LOGICAL OR PHYSICAL BLOCK NUMBER ; WD. 20 -- NOT USED ; ; DRIVE USUAGE OF UCB ; ; U.CW2+1 --- STORES DRIVER'S RETRY COUNT ; ;+ ; THE TU58 UTILIZES RADIAL SERIAL PROTOCOL. ALL I/O ; COMMANDS ARE INITIATED BY SENDING A COMMAND MESSAGE ; PACKET CONSISTING OF 14. BYTES OF INFORMATION. DATA ; IS THEN TRANSFERRED TO THE UNIT (WRITE) OR TO THE ; USER'S BUFFER (READ) IN MESSAGE PACKETS OF UP TO 128 ; BYTES EACH. TERMINATION OF AN OPERATION BY THE TU58 ; IS SIGNALED BY THE UNIT'S SENDING AN END MESSAGE ; PACKET WHICH CONTAINS INFORMATION CONCERNING THE ; SUCCESS OF THE TRANSFER. ;- ; ; MOVB #RTRY,U.CW2+1(R5) ;STORE RETRY COUNT CALL @VOLVD ;VALIDATE VOLUME VALID BCC 10$ ;IF CC SUCCESS 5$: JMP XIT ;EXIT 10$: TST R0 ;TRANSFER FUNCTION? BPL 5$ ;IF PL NO MOV S.CSR(R4),DBUF(R3) ;STORE DL11 BUFFER ADDRESS MOV R3,R4 ;R4 IS USED FOR CONTROLLER INDEXING CALL @BLKCK ;CHECK PARAMETERS ADD #DDXBF,DBUF(R4) ;SAVE DL11 XMITTER BUFFER ; ; SEND COMMAND PACKET ; RINI: MOV #TYPTAB-2,RADD(R4); POINT TO WORD PRIOR TO TABLE CLR FLAG(R4) ;SET FLAG FOR TRANSMIT INTERRUPTS CLR FLGTYP(R4) ;CLEAR FLAG TYPE WORD,DEFAULT IS OLD TU58 BR 145$ ;PREPARE TO SEND BYTE RINI1: MOV #CTAB-2,RADD(R4) ;POINT TO WORD PRIOR TO TABLE BIC #TU58C!TRNACK,FLGTYP(R4); CLEAR ACK AND TU58 CONTINUE FLAG CLR FLAG(R4) ;SET FLAG FOR TRANSMIT INTERRUPTS BR 145$ ;PREPARE TO SEND BYTE ; ; SEND COMMAND PACKET. ; CHALF: BITB #NTU58,FLGTYP(R4) ; NEW TU58 ? BNE 15$ ; YES JMP RTBK ; NO - DON'T SEND INITIAL CONTINUE 15$: MOVB #CONT,@DBUF(R4) ; SEND CONTINUE TO ASSURE A RESPONSE BR 145$ ; PREPARE TO SEND BYTE CONE: MOVB #CNTL,@DBUF(R4) ;SEND COMMAND FLAG BYTE BR 145$ ;PREPARE TO SEND BYTE CTWO: MOV #10.,@DBUF(R4) ;SEND BYTE COUNT MOVB #10.,CKSM1+1(R4) ;CREATE CHECKSUM WORD FROM MOVB #CNTL,CKSM1(R4) ; FIRST TWO BYTES BR 145$ CTHR: CALL IOPKT ;STORE I/O PKT ADDRESS IN R1 ; ; POSITION AND DIAGNOSE FUNCTIONS ARE USER MODE DIAGNOSTIC FUNCTIONS ; CMP #IO.DGN!IQ.UMD,I.FCN(R1) ;TU58 INTERNAL DIAGNOSTICS? BNE 40$ ;IF NE NO MOV #DIAG,CKSM2(R4) ;CREATE NEXT CHECKSUM WORD MOVB #DIAG,@DBUF(R4) ;SEND DIAGNOSTIC OP CODE BR 140$ ;CONTINUE OPERATION 40$: CMP #IO.BLS!IQ.UMD,I.FCN(R1) ;POSITION FUNCTION? BNE 60$ ;IF NE NO MOV #POSIT,CKSM2(R4) ;CREATE NEXT CHECKSUM WORD MOVB #POSIT,@DBUF(R4) ;SEND OP CODE BR 140$ ;CONTINUE 60$: CMPB #IO.RLB/256.,I.FCN+1(R1) ;READ LOGICAL BLOCK? BNE 72$ ; IF NO NE MOV #READ,CKSM2(R4) ;CREATE NEXT CHECKSUM WORD MOVB #READ,@DBUF(R4) ;SEND READ OPCODE BR 110$ ;CONTINUE 72$: CMPB #IO.WLB/256.,I.FCN+1(R1); WRITE LOGICAL BLOCK? BEQ 100$ ;IF EQ YES MOV (SP)+,R1 ;RESTORE R1 CALL @FORK ;ENSURE PRIORITY=0 AND REGISTERS SAVED MOV #IE.IFC&377,R0 ;ILLEGAL FUNCTION CODE CLR CKSM2(R4) ;CLEAR BYTES TRANSFERRED COUNT JMP IOCMP ;EXIT 100$: MOV #WRITE,CKSM2(R4) ;CREATE NEXT CHECKSUM WORD MOVB #WRITE,@DBUF(R4) ;SEND WRITE OPCODE 110$: BITB #US.WCK,U.STS(R5) ;WRITE CHECK SET? BNE 141$ CMPB #20,I.FCN(R1) ;IS WLC OR RLC REQUESTED? BNE 140$ ;IF NE NO BR 141$ ; ; SEND A MODIFIER BYTE OF ONE FOR WRITECHECKS AND READCHECKS ; CFOUA: MOVB #1,CKSM2+1(R4) ;ALTER CHECKSUM MOVB #1,@DBUF(R4) ;SEND MODIFIER ADD #2,RADD(R4) ;SKIP OVER NEXT RETURN ADDRESS BR 160$ ;CONTINUE 140$: ADD #2,RADD(R4) ;SKIP OVER NEXT RETURN ADDRESS 141$: MOV (SP)+,R1 ;RESTORE R1 MOV CKSM2(R4),WORD1(R4) ;STORE OP CODE AND COMMAND MODIFIER 145$: JMP SMSG ; ; SEND A MODIFIER BYTE OF ZERO FOR READS AND WRITES ; CFOUB: CLRB @DBUF(R4) ;SEND MODIFIER 160$: CALL CHKPT ;CHECKSUM CALCULATION BR 145$ CFIV: MOVB U.UNIT(R5),@DBUF(R4) ;SEND UNIT # MOVB U.UNIT(R5),CKSM2(R4) BR 145$ CSIX: BITB #NTU58,FLGTYP(R4) ;OLD TU58 ? BEQ 162$ ;YES MOVB #FLCTL,@DBUF(R4); SET FLOW CONTROL BIT IN SWITCH WORD MOVB #FLCTL,CKSM2+1(R4); KEEP TRACK OF CHECKSUM BR 160$ ; 162$: CLRB @DBUF(R4) ; SEND 0 CLRB CKSM2+1(R4) BR 160$ CSEV: CEIG: CLRB @DBUF(R4) ;SEND TWO ZERO BYTES BR 145$ CNIN: CALL IOPKT ;STORE I/O PACKET ADDRESS IN R1 ADD #I.PRM,R1 ;POINT TO PARAMETERS MOV (R1)+,U.BUF(R5) ;INSERT RELOCATION BIAS MOV (R1)+,U.BUF+2(R5) ;INSERT BUFFER ADDRESS MOV (R1),CKSM2(R4) ;CREATE CHECKSUM MOVB (R1),@DBUF(R4) ;SEND LOW BYTE COUNT BR 141$ ; ; NOTE: ; ; THE TU58 REQUIRES THAT THE NUMBER OF BYTES TO BE TRANSFERRED ; BE EVEN AND THAT THE STARTING ADDRESS OF THE DATA TRANSFER BE ; ON A WORD BOUNDARY. ; CTWE: ;SEND HIGH BLOCK NO. CTEN: MOVB CKSM2+1(R4),@DBUF(R4) ;SEND HIGH BYTE COUNT BR 160$ CELE: CALL IOPKT ;STORE I/O PKT ADDRESS IN R1 MOVB I.PRM+12(R1),@DBUF(R4) ;SEND LOW BLOCK NO. MOV I.PRM+12(R1),CKSM2(R4) BR 141$ CTHI: MOVB CKSM1(R4),@DBUF(R4) ;SEND LOW CHECKSUM BR 145$ CFOR: MOVB CKSM1+1(R4),@DBUF(R4) ;SEND HIGH CHECKSUM ; ; AFTER THE COMMAND PACKET IS SENT THE TU58 RESPONDS. ; ITS RESPONSE DEPENDS ON THE OPERATION REQUESTED. ; A CONTINUE IS SENT IN RESPONSE TO A WRITE, THE FIRST ; DATA PACKET IS SENT IN RESPONSE TO A READ, AND AN ; END PACKET IS SENT IN RESPONSE TO A DIAGNOSTIC OR ; POSITION COMMAND. ALSO AN END PACKET MAY BE RECEIVED ; ON A FAILURE TO READ THE FIRST RECORD PROPERLY. ; ; DETERMINE THE APPROPRIATE INITIAL RESPONSE FROM THE TU58 ; AND RECEIVE THE FIRST BYTE FROM THE TU58. ; INCB FLAG+1(R4) ;SET FLAG FOR RECEIVE SUB #DDXBF-DDRBF,DBUF(R4) ;SET RECEIVE BUFFER BR 25$ ;READ THE RESPONSE BYTE FROM TU58 CFIF: CALL IOPKT ;STORE I/O PKT ADDRESS IN R1 CMPB #IO.DGN/256.,I.FCN+1(R1) ;DIAGNOSTIC? BEQ 170$ ;IF EQ YES JMP DPACK ;ELSE DATA PACKET OR CONTINUE 170$: MOV (SP)+,R1 ;RESTORE R1 BR ENDP ;DO END PACKET PROCESSING ; ; DETERMINE TU58 TYPE COMMAND ; TYPTHR: MOV #TYPU58,CKSM2(R4); CREATE NEXT CHECKSUM WORD MOVB #TYPU58,@DBUF(R4); SEND TU58 TYPE OPCODE JMP 145$ ;PREPARE TO SEND BYTE TYPSIX: MOVB #FLCTL,@DBUF(R4); SET FLOW CONTROL BIT IN SWITCH BYTE MOVB #FLCTL,CKSM2+1(R4); CREATE CHECKSUM JMP 160$ ; CREATE CHECKSUM TYPSEV: CLRB @DBUF(R4) ; NOT IMPORTANT FOR COMMAND PACKET JMP 145$ ; PREPARE TO SEND BYTE TYPFIF: CMPB RDAT(R4),#END ;NEW TU58? (WILL RETURN END PACKET) BNE 200$ ;NO BIS #NTU58!CHKDON!TRNACK,FLGTYP(R4); SET FLAG TO NEW TU58 BR 206$ ; FLUSH END PACKET 200$: CMPB RDAT(R4),#DATA ; DATA PACKET - OLD TU58 ? BEQ 204$ ; YES - FLUSH DATA PACKET JMP NTRY ; RETRY 204$: BIS #CHKDON,FLGTYP(R4); TU58 TYPE CHECK IS COMPLETE JMP NTRY1 ;FLUSH DATA PACKET BY DOING INIT 206$: ADD #DDXBF-DDRBF,DBUF(R4); POINT TO TRANSMITTER BUFFER JMP SMSG ; SEND A CONTINUE TYPSXT: JMP RMSG ; FLUSH THE REST OF THE END PACKET TYPSVT: ADD #DDXBF-DDRBF,DBUF(R4); POINT TO TRANSMITTER BUFFER JMP RINI1 ; NEW TU58 - USE MRSP ; ; RECEIVE AND MANIPULATE THE TU58'S END PACKET INFORMATION ; ENDP: MOV #ETAB-2,RADD(R4) ;POINT TO END PACKET SEQUENCE CMPB RDAT(R4),#CNTL ;COMMAND/END PACKET? BR 24$ ; ; AT EONE WE SHOULD HAVE RECEIVED THE BYTE COUNT OF AN END PACKET ; WHICH IS ALWAYS EQUAL TO 10. ; EONE: CMPB RDAT(R4),#10. ;BYTE COUNT=10.? 24$: BEQ 25$ ;IF EQ YES JMP NTRY ; 25$: JMP RMSG ;READ A BYTE ETWO: CMPB RDAT(R4),#100 ;OP CODE=END PACKET? BR 24$ ETHR: MOVB RDAT(R4),CKSM1(R4) ;STORE SUCCESS CODE MOVB RDAT(R4),WORD2(R4) ; BR 25$ ; EFOU: MOVB RDAT(R4),WORD2+1(R4) ;STORE UNIT SELECT EFIV: ;DUMP BYTES ESIX: ESEV: BR 25$ EEIG: MOVB RDAT(R4),CKSM2(R4) ;STORE BYTE TRANSFERRED COUNT -LOW MOVB RDAT(R4),WORD3(R4) ; BR 25$ ENIN: MOVB RDAT(R4),CKSM2+1(R4) ;STORE BYTE TRANSFERRED COUNT -HIGH MOVB RDAT(R4),WORD3+1(R4) ; ETEN: EELE: ETWE: BR 25$ ;DUMP BYTES ETHI: CALL @FORK ;ENSURE PRIORITY=0 AND REGISTERS SAVED MOV #IS.SUC&377,R0 ;ASSUME SUCCESS TSTB CKSM1(R4) ;SUCCESSFUL? BGT ERRPT ;IF GT YES, BUT HAD RETRIES BEQ ENDOP ;IF EQ, COMPLETE SUCCESS MOV #IE.DNR&377,R0 ;ASSUME DEVICE NOT READY CMPB CKSM1(R4),#-9. ;CARTRIDGE NOT IN PLACE? BEQ ERRPT ;IF EQ YES MOV #IE.WLK&377,R0 ;ASSUME WRITE-LOCKED CMPB CKSM1(R4),#-11. ;WRITE-LOCKED? BEQ ERRPT ;IF EQ YES MOV #IE.FHE,R0 ;ASSUME FATAL HARDWARE ERROR CMPB CKSM1(R4),#-33. ;MOTOR STOPPED? BEQ ERRPT ;IF EQ YES MOV #IE.VER&377,R0 ;ASSUME UNRECOVERABLE ERROR ERRPT: CALL LOGERR ;LOG DEVICE ERROR BR ENDOP ; ;+ ; **-LOGERR-LOG DEVICE ERROR ; **-LOGTMO-LOG DEVICE TIMEOUT ; ; ; ALLOCATE A CORE BLOCK, FILL IT WITH THE APPROPRIATE INFORMATION, ; CALL THE EXECUTIVE ERROR LOGGING ROUTINE, DEALLOCATE THE CORE ; BLOCK, AND RETURN BACK TO THE CALLER. ; ; IF FOR ANY REASON THE CORE BLOCK CANNOT BE ALLOCATED THEN ; THE EXECUTIVE ERROR LOGGING ROUTINE WILL NOT BE CALLED ; AND THE ERROR SEQUENCE NUMBER WILL BE UPDATED TO INDICATE ; THAT A MISSED ERROR CONDITION OCCURRED. ;- LOGERR: MOV R0,-(SP) ;SAVE STATUS CODE MOV DVERR,-(SP) ;TO LOG DEVICE ERROR BR 70$ ; LOGTMO: MOV R0,-(SP) ;SAVE STATUS CODE MOV DTOER,-(SP) ;TO LOG DEVICE TIMEOUT 70$: MOV #DDNUM*2,R1 ;NUMBER OF BYTES TO ALLOCATE CALL @ALOCB ;ALLOCATE A CORE BLOCK BCC 80$ ;IF CC BLOCK WAS ALLOCATED TST (SP)+ ; POP CO-ROUTINE ADDRESS THAT WAS PUT ON INC @ERRSQ ;INDICATE A MISSED ERROR CONDITION BR 90$ ;END I/O ROUTINE 80$: MOV R0,R1 ;COPY CORE BUFFER POINTER MOV DBUF(R4),R3 ;STORE BUFFER ADDRESS TST -(R3) ;POINT TO DL11 CSR MOV (R3)+,(R1)+ ;MOVE DL11 RECEIVE CSR INTO CORE BUFFER MOV (R3)+,(R1)+ ;...DL11 RECEIVE BUFFER MOV (R3)+,(R1)+ ;... DL11 TRANSMITTER CSR MOV WORD1(R4),(R1)+ ;OPCODE AND COMMAND MODIFIER MOV WORD2(R4),(R1)+ ;SUCCESS CODE AND UNIT SELECT MOV WORD3(R4),(R1) ;BYTE COUNT LOW AND BYTE COUNT HIGH MOV R4,R3 ;SAVE CONTROLLER INDEX MOV U.SCB(R5),R4 ;GET SCB ADDRESS MOV R0,R2 ;SET WITH CORE BUFFER POINTER CALL @(SP)+ ;CALL ERROR LOGGING ROUTINE MOV R2,R0 ;RESTORE CORE BUFFER POINTER MOV R3,R4 ;RESTORE CONTROLLER INDEX MOV #DDNUM*2,R1 ;GET NUMBER OF BYTES TO DEALLOCATE CALL @DEACB ;DEALLOCATE CORE BLOCK 90$: MOV (SP)+,R0 ;RESTORE I/O STATUS CODE RETURN ENDOP: CALL IOPKT CMPB #IO.DGN/256.,I.FCN+1(R1) ;DIAGNOSTIC? BNE 95$ ;IF NE NO MOV I.PRM+14(R1),@KISR6 ;SET BUFFER RELOCATION BIAS MOV I.PRM+16(R1),R0 ;GET REGISTER BUFFER ADDRESS MOV DBUF(R4),R3 ;GET DL11 RECEIVE BUFFER ADDRESS TST -(R3) ;POINT TO REC. CSR ADDRESS MOV (R3)+,(R0)+ ;MOV REC. CSR CONTENTS TO USER BUFF. MOV (R3)+,(R0)+ ;MOV REC. BUFF CONTENTS MOV (R3)+,(R0)+ ;MOV TRANS. CSR CONTENTS MOV (R3)+,(R0)+ ;MOV TRANS. BUFF CONTENTS MOV CKSM1(R4),(R0) ;MOV TU58 END PACKET INFO MOV #IS.SUC&377,R0 ;STORE I/O COMPLETION STATUS 95$: TST (SP)+ ;RESTORE STACK ; ; COMMON EXIT CODE-ALL OPERATIONS COMPLETE HERE ; IOCMP: MOV CKSM2(R4),R1 ;PICKUP BYTES TRANSFERRED COUNT XIT: MOVB U.CW2+1(R5),R2 ;STORE FINAL RETRY COUNT BIS #RTRY*^D<256>,R2 ;MERGE INTIAL RETRY COUNT CALL @IODON JMP DDINI ;NEXT I/O PACKET .DSABL LSB ; ; WE ENTER HERE WHEN AN UNEXPECTED AND UNDESIRED BYTE IS RECEIVED. ; THE TU58 IS REINITIALIZED AND IF THE RETRY COUNT IS => 0, THE ; I/O FUNCTION IS STARTED OVER. OTHERWISE, AN ERROR IS LOGGED AND ; THE OPERATION IS ABORTED. ; .ENABL LSB NTRY: DECB U.CW2+1(R5) ;DECREMENT RETRY COUNT NTRY1: ADD #DDXBF-DDRBF,DBUF(R4); POINT TO TRANSMITTER BUFFER ; ; TINIT TRIES TO REINITIALIZE THE TU58. IT WILL ATTEMPT THE ; INITIALIZATION ROUTINE OF SENDING BREAK, CLEARING BREAK, ; SENDING TWO INIT'S, AND RECEIVING A CONTINUE. ; TINIT: CLR FLAG(R4) ;SET FOR TRANSMIT WITH NO USER DATA TRANSFER MOV #ITAB-2,RADD(R4) ;POINT TO INITIALIZE TABLE BR 50$ ;WAIT ; ; NULL TIMING CHARACTERS ARE SENT AT IONE AND ITWO TO ALLOW ; ENOUGH TIME FOR THE BREAK BIT TO CAUSE A FRAMING ERROR. THIS ; SIGNALS THE TU58 TO STOP TRANSMITTING AND LISTEN. ; IONE: MOV DBUF(R4),CKSM1(R4) ;TEMP. STORE BUFFER SUB #DDXBF-DDXCS,CKSM1(R4) ;POINT TO XCSR BIS #BRK,@CKSM1(R4) ;SEND BREAK TO TU58 ITWOA: ;SEND TIMING NULLS ITWOB: ITWOC: ITWOD: ITWOE: CLRB @DBUF(R4) ;SEND ANOTHER NULL 50$: JMP SMSG ;WAIT ; ; ITHR AND IFOU WILL CLEAR THE BREAK CONDITION AND ISSUE ; TWO INITIALIZE COMMANDS TO THE TU58. (THE FIRST IS IGNORED ; BY THE CONTROLLER). ; ITHR: BIC #BRK,@CKSM1(R4) ;CLEAR BREAK SUB #DDXCS-DDRBF,CKSM1(R4) ;TEMP. STORE REC. BUFFER TSTB @CKSM1(R4) ;DUMP REC. BUFFER IFOU: MOVB #INIT,@DBUF(R4) ;SEND ANOTHER INIT. BR 50$ ;WAIT ; ; A CHARACTER IS RECEIVED AT ISIX. IF IT IS A CONTINUE, WE ; HAVE SUCCESSFULLY INITIALIZED THE DEVICE. ; IFIV: SUB #DDXBF-DDRBF,DBUF(R4) ;POINT TO REC. BUFF. INCB FLAG+1(R4) ;SET FLAG FOR RECEIVE BISB #TU58C,FLGTYP(R4) ; TU58 MUST SEND A CONTINUE NOW JMP RMSG ;WAIT ISIX: ADD #DDXBF-DDRBF,DBUF(R4) ;POINT TO XBUF BICB #TU58C,FLGTYP(R4) ; TU58 CONTINUE ALREADY SENT - CLEAR FLAG TSTB U.CW2+1(R5) ;RETRY? BGT 60$ ;IF GT YES CALL @FORK ;ENSURE PRIORITY=0 AND REGISTERS SAVED MOV #IE.FHE&377,R0 ;FATAL ERROR CLR CKSM2(R4) ;CLEAR BYTE TRANSFER COUNT MOV #200,CKSM1(R4) ;SET ERROR CODE SUB #DDXBF-DDRBF,DBUF(R4) ;POINT TO REC. BUFFER JMP ERRPT ;ERROR LOG AND EXIT 60$: BITB #NTU58,FLGTYP(R4); NEW TU58 ? BNE 62$ ;YES BITB #CHKDON,FLGTYP(R4); COMPLETED TU58 TYPE CHECK ? BNE 62$ ;YES - IT MUST BE OLD TU58 JMP RINI ;DETERMINE TU58 TYPE - RETRY 62$: JMP RINI1 ;SEND COMMAND PACKET - RETRY ; ; HERE DATA PACKETS SENT BY THE TU58 ARE READ. THE NUMBER OF ; DATA BYTES IN THE PACKET IS RECEIVED AT RONE. IT IS STORED ; IN LOCATION FLAG AND THE CHECKSUM IS INITIALIZED. THE DATA ; IS TRANSFERRED WITHIN THE INTERRUPT SERVICE ROUTINE WHERE ; THE CHECKSUM IS ALSO VERIFIED. THE FIRST BYTE OF THE NEXT ; PACKET IS RECEIVED AT RFOU AND IF IT IS A DATA FLAG, THIS ; CODE IS ENTERED AGAIN. ; DPACK: CMPB #IO.RLB/256.,I.FCN+1(R1) ;READ? BNE 102$ ;IF NE NO -IT'S A WRITE MOV (SP)+,R1 ;RESTORE R1 RFOU: CMPB RDAT(R4),#DATA ;DATA PACKET? BEQ 96$ ;IF EQ YES 94$: JMP ENDP 96$: MOVB #DATA,CKSM1(R4) ;START CHECKSUM MOV #RTAB-2,RADD(R4) ;POINT TO READ TABLE BR 100$ ;READ A BYTE RONE: MOVB RDAT(R4),FLAG(R4) ;STORE BYTE COUNT MOVB RDAT(R4),CKSM1+1(R4) ;STORE HIGH BYTE OF FIRST CHECKSUM 100$: JMP RMSG ; ; AT THIS POINT WE SEND A DATA PACKET TO THE TU58. ; THE DATA FLAG BYTE IS SENT AT TONE. THE NUMBER OF DATA ; BYTES IN THIS PACKET IS SENT AT TTWO. DATA IS THEN ; TRANSFERRED ALONG WITH THE CHECKSUM WITHIN THE INTERRUPT ; SERVICE ROUTINE. RETURN TO THIS SEGMENT IS MADE AT TFIV ; AND THE FIRST BYTE OF THE NEXT PACKET IS RECEIVED AT ; TSIX, IF IT IS A CONTINUE ANOTHER PACKET IS SENT. ; WHEN THE TU-58 HAS RECEIVED ALL THE DATA IT SENDS AN ; END PACKET FLAG INSTEAD OF A CONTINUE (THIS ALSO OCCURS ; IF THE TU58 ENCOUNTERS AN ERROR WRITING THE DATA). ; 102$: MOV I.PRM+4(R1),WCNT(R4) ;DUPLICATE BYTE COUNT MOV (SP)+,R1 ;RESTORE R1 TSIX: BICB #TU58C,FLGTYP(R4) ; TU58 ALREADY SENT CONTINUE - CLEAR FLAG CMPB RDAT(R4),#CONT ; CONTINUE FLAG ? BNE 94$ ;IF NE NO MOV #TTAB-2,RADD(R4) ;POINT TO TRANSMIT (WRITE) TABLE CLRB FLAG+1(R4) ;SET TRANSMIT FLAG ADD #DDXBF-DDRBF,DBUF(R4) ;SET TRANSMIT BUFFER BR 130$ ;PREPARE TO SEND FIRST BYTE TONE: MOVB #DATA,@DBUF(R4) ;SEND FLAG BYTE MOVB #DATA,CKSM1(R4) ;START CHECKSUM CMP #128.,WCNT(R4) ;MORE THAN 1 PACKET LEFT? BLO 120$ ;IF L0 YES 125$: MOVB WCNT(R4),CKSM1+1(R4) ;CREATE HIGH BYTE OF CHECKSUM CLRB WCNT(R4) ;ZERO REMAINING BYTE COUNT BR 130$ 120$: MOVB #128.,CKSM1+1(R4) ;CREATE HIGH BYTE OF CHECKSUM SUB #128.,WCNT(R4) ;ADJUST REMAINING COUNT 130$: JMP SMSG TTWO: MOVB CKSM1+1(R4),@DBUF(R4) ;SEND BYTE COUNT MOVB CKSM1+1(R4),FLAG(R4) ;SET UP FLAG BYTE COUNT BR 130$ TFIV: INCB FLAG+1(R4) ;SET RECEIVE BYTE SUB #DDXBF-DDRBF,DBUF(R4) ;SET RECEIVE BUFFER BISB #TU58C,FLGTYP(R4) ;TU58 CAN SEND CONTINUE FOR MORE DATA BR 100$ ;READ A BYTE .DSABL LSB ; ; IOPKT PUTS I/O PACKET ADDRESS IN R1 ; ; OUTPUT: ; ; R1 = I/O PACKET ADDRESS ; (SP) = FORMER CONTENTS OF R1 TO BE RESTORED BY THE CALLER ; IOPKT: MOV (SP)+,WCNT(R4) ;SAVE RETURN ADDRESS MOV R1,-(SP) ;PRESERVE R1 MOV R4,-(SP) ;PRESERVE R4 MOV U.SCB(R5),R4 ;GET SCB ADDRESS MOV S.PKT(R4),R1 ;GET I/O PKT ADDRESS MOV (SP)+,R4 ;RESTORE R4 JMP @WCNT(R4) ;NOTE R1 WILL BE RESTORED BY PROGRAM ; ; RTBK (RETURN BACK) INCREMENTS THE RETURN ADDRESS POINTER AND ; THEN JUMPS THERE. ; RTBK: ADD #2,RADD(R4) ;POINT TO NEXT LOCATION MOV @RADD(R4),-(SP) ;MOVE RETURN ADDRESS LOCATION ONTO STACK JMP @(SP)+ ;RETURN TO ADDRESS IN TABLE ; ; THIS ROUTINE IS JUMPED TO IN ORDER TO SEND INFORMATION. ; THE MAIN PROGRAM CONTINUES VIA THE INTERRUPT SERVICE ROUTINE ; CODE (SPT), UNLESS WRITE DATA IS TO BE TRANSFERRED (DATA COUNT ; FLAG = NON-ZERO). ; .ENABL LSB SMSG: SUB #DDXBF-DDXCS,DBUF(R4) ;POINT TO CSR BIT #TRDY,@DBUF(R4) ;IS TRANSMITTER READY BEQ 20$ SREC: ADD #DDXBF-DDXCS,DBUF(R4) ;POINT TO BUFFER BITB #NTU58,FLGTYP(R4); NEW TU58 ? BEQ 16$ ;NO BITB #TRNACK,FLGTYP(R4) ; ACK CHAR FOR NEW TU58 MRSP ? BEQ 16$ ; NO MOVB #CONT,@DBUF(R4) ;MUST BE READING FROM TU58 ;ACK TU58 THAT CHAR HAS BEEN RECEIVED BICB #TRNACK,FLGTYP(R4); COMPLETED THE ACKNOWLEDGE JMP RPT1 ;PROCESS THE CHAR JUST READ 16$: TSTB FLAG(R4) ;BYTE COUNT 0 BEQ RTBK ;IF EQ YES JMP SPT ;GO TO SEND DATA ROUTINE 20$: BIS #S2.ACT,S.ST2(R4) ;SET I/O ACTIVE BIT BIS #TIE,@DBUF(R4) ;SET TRANS. INTER. ENABLE MOV U.SCB(R5),R4 ;STORE SCB ADDRESS MOVB S.ITM(R4),S.CTM(R4) ;SET TIMEOUT RETURN .DSABL LSB ; ; THIS ROUTINE IS JUMPED TO IN ORDER TO RECEIVE INFORMATION VIA ; THE DL11. IF RECEIVER DONE IS SET, THEN A RETURN TO THE MAIN ; PROGRAM IS INITIATED VIA THE INTERRUPT SERVICE ROUTINE (RPT). ; IF THE DL11 DONE BIT IS CLEAR, A RETURN IS EXECUTED AND THE ; INTERRUPT SERVICE ROUTINE WILL RETURN CONTROL TO THE PROGRAM ; WHEN THE DONE BIT IS SET AND WHEN ALL READ DATA HAS BEEN ; TRANSFERRED TO THE USER'S BUFFER. ; .ENABL LSB RMSG: SUB #DDRBF-DDRCS,DBUF(R4) ;POINT TO CSR BIT #RDONE,@DBUF(R4) ;BYTE READY? BEQ 20$ ;IF EQ NO RREC: JMP RPT ;IF YES ENTER READ ROUTINE 20$: BIS #S2.ACT,S.ST2(R4) ; BIS #RIE,@DBUF(R4) ;SET REC. INTERRUPT ENABLE MOV U.SCB(R5),R4 ;RESTORE SCB ADDRESS MOVB #40.,S.CTM(R4) ;SET TIMEOUT RETURN .DSABL LSB ; ; CHKPT CREATES A CHECKSUM ; ; INPUT: ; ; CKSM2(R4) = WORD TO BE ADDED ; CKSM1(R4) = OLD CHECKSUM ; ; OUTPUT: ; ; CKSM1(R4) = NEW CHECKSUM ; CHKPT: ADD CKSM2(R4),CKSM1(R4) ;ADD TWO WORDS ADC CKSM1(R4) ;ADD CARRY ;FALL THROUGH TO RETURN ; ; END LOCAL ROUTINES ; ;+ ; DDCAN-CANCEL I/O ENTRY POINT ; CANCEL I/O IS A NOP FOR FILE STRUCTURED DEVICES. ;- DDCAN: RETURN ;+ ; **-DDKRB-CONTROLLER ONLINE/OFFLINE ROUTINE ; DDKRB: BCS 20$ ;IF CS OFFLINE REQUEST TST EXEVEC ;IF DONE ALREADY BNE 20$ ;SKIP THIS MOV R2,-(SP) ;SAVE R2 MOV R3,-(SP) ;SAVE R3 MOV KINAR6,-(SP) ;SAVE KINAR6 MOV @#112,R0 ;GET ADDRESS OF TABLE OF ENTRIES MOV (R0),R0 ;GET ADDRESS OF APR BIAS (1ST WORD IN TABLE) MOV (R0),KINAR6 ;MAP COMMON THROUGH I-SPACE APR6 MOV #EXEVEC,R3 ;POINT TO VECTOR MOV #EXEVCL,R2 ;SPECIFY LENGTH OF VECTOR CALL @#140004 ;TRANSLATE THE VECTOR MOV (SP)+,KINAR6 ;RESTORE KINAR6 MOV (SP)+,R3 ;RESTORE R3 MOV (SP)+,R2 ;RESTORE R2 20$: RETURN ;+ ; POWERFAIL REQUIRES NO OPERATION. REINITIALIZATION ; OF THE TU58 WILL OCCUR DURING NORMAL OPERATION IF REQUIRED. ;- DDPWF: RETURN ;+ ; **-DDUCB-UNIT ONLINE/OFFLINE ROUTINE ;- DDUCB: RETURN ;+ ; **-$DDINT TU58 INTERRUPT SERVICE ROUTINE ; ; INTERRUPTS ARE ISSUED WHEN EITHER THE ; RECEIVE OR TRANSMIT CSR'S INTERRUPT ; ENABLE IS SET BY ROUTINES RMSG OR ; SMSG. THEY INDICATE THAT THE DL-11 ; HAS RECEIVED A BYTE OF INFORMATION ; OR CAN ACCEPT A BYTE OF INFORMATION ; FOR TRANSMITTING. ;- .ENABL LSB $DDOUT:: ;;;2 INT. ENTRY PTS INTSE$ DD,PR4,T$$U58 ;;;SAVE REGISTERS & SET PRIORITY BIC #,@DBUF(R4) ;;;CLEAR INTERRUPTS MOV R1,-(SP) ;;;SAVE R1 MOV U.SCB(R5),R1 ;;;GET SCB ADDRESS CLRB S.CTM(R1) ;;;CLEAR TIMEOUT MOV (SP)+,R1 ;;;RESTORE R1 ; ; FLAG+1 IS SET FOR A TRANSMIT OPERATION AND CLEARED FOR ; A RECEIVE OPERATION. FLAG IS CHECKED TO DETERMINE IF WE ; HAVE DATA TO TRANSFER. ; TSTB FLAG+1(R4) ;;;RECEIVE INTERRUPT? BEQ 3$ ;IF EQUAL NO BIT #TRNACK,FLGTYP(R4); IN PROCESS OF ACKNOWLEDGING CHAR ? BEQ RPT ;NO -- JUST A RECEIVE INTERRUPT ADD #DDXBF-DDXCS,DBUF(R4); POINT TO TRANSMIT BUFFER MOVB #CONT,@DBUF(R4) ;ACK THE CHAR THAT WAS READ BICB #TRNACK,FLGTYP(R4); COMPLETED THE ACKNOWLEDGE JMP RPT1 ; CONTINUE WITH THE RECEIVE INTERRUPT 3$: ADD #DDXBF-DDXCS,DBUF(R4) ;;;POINT TO BUFFER TSTB FLAG(R4) ;;;TRANSMIT DATA PACKET? BNE SPT ;;;IF NE YES 5$: JMP RTBK ;;;ELSE RETURN ; ; SPT IS THE CODE USED TO SEND USER DATA TO THE TU58. A RUNNING ; CHECKSUM IS KEPT AND IS SENT AS THE LAST TWO CHARACTERS OF A ; DATA PACKET (TTHR,TFOU). AFTER ALL DATA HAS BEEN SENT, CONTROL ; IS PASSED TO THE MAIN PROGRAM. ; SPT: CALL @GTBYT ;;;PUT USER'S DATA BYTE ON STACK BITB #1,FLAG(R4) ;;;CHECK FOR EVEN OR ODD BYTE NO. BNE 20$ ;;;IF NE ODD,THEREFORE HIGH ORDER ;;;BYTE IN CHECKSUM MOVB (SP)+,CKSM2(R4) ;;;SAVE LOW ORDER CHECKSUM BYTE MOVB CKSM2(R4),@DBUF(R4) ;;;TRANSMIT BYTE BR 30$ 20$: MOVB (SP)+,CKSM2+1(R4) ;;;SAVE HIGH ORDER CHECKSUM BYTE MOVB CKSM2+1(R4),@DBUF(R4) ;;;TRANSMIT BYTE CALL CHKPT ;;;GENERATE CHECKSUM 30$: DECB FLAG(R4) ;;;DECREMENT DATA COUNT 35$: JMP SMSG TTHR: MOVB CKSM1(R4),@DBUF(R4) ;;;SEND LOW ORDER CHECKSUM BYTE BR 35$ TFOU: MOVB CKSM1+1(R4),@DBUF(R4) ;;;SEND HIGH ORDER BYTE BR 35$ TFOUA: BITB #NTU58,FLGTYP(R4); NEW TU58 ? BNE 39$ ; YES 38$: JMP RTBK ; NO - CONTINUE NOT NEEDED FOR RSP 39$: MOVB #CONT,@DBUF(R4) ; SEND CONTINUE AFTER TRANSMITTING DATA PACKET BR 35$ ; ; ; RPT CHECKS FOR AN ERROR CONDITION IN THE DL11'S RECEIVE ; BUFFER. IF DATA IS TO BE RECEIVED THIS ROUTINE TRANSFERS ; THE CHARACTER IN THE USER'S BUFFER AND KEEPS A RUNNING ; CHECKSUM. AFTER ALL DATA IS RECEIVED, THE FINAL TWO BYTES ; OF THE PACKET ARE PRESENT AT RTWO AND RTHR AND IF THEY EQUAL ; THE CHECKSUM, THEN CONTROL IS RETURNED TO THE MAIN PROGRAM. ; RPT: ADD #DDRBF-DDRCS,DBUF(R4) ;;;POINT TO BUFFER MOV @DBUF(R4),RDAT(R4) ;;;STORE RECEIVED INFO. BPL 80$ ;;;IF PL NO ERROR 40$: JMP NTRY ;;;ATTEMPT RETRY 80$: BITB #NTU58,FLGTYP(R4); NEW TU58 ? BEQ RPT2 ;NO-DO NOT HAVE TO ACKNOWLEDGE THE DATA BITB #TU58C,FLGTYP(R4) ; DATA COULD BE A CONTINUE IF FLAG SET ? BEQ 82$ ; NO - MUST ACK IT CMPB RDAT(R4),#CONT ; IS DATA A CONTINE ? BEQ RPT2 ; YES - THE CONTINUE IS FROM TU58 - NO ACK 82$: BIS #TRNACK,FLGTYP(R4); YES - MUST ACKNOWLEDGE IT ADD #DDXBF-DDRBF,DBUF(R4); POINT TO TRANSMIT BUFFER JMP SMSG ;NEW TU58-ACKNOWLEDGE CHAR JUST READ RPT1: SUB #DDXBF-DDRBF,DBUF(R4); POINT TO RECEIVE BUFFER RPT2: TSTB FLAG(R4) ;;;DATA TO RECEIVE BEQ 5$ ;;;IF EQ NO MOVB RDAT(R4),-(SP) ;;;PUT DATA ON STACK CALL @PTBYT ;;;PUT DATA INTO USER'S BUFFER BITB #1,FLAG(R4) ;;;ODD OR EVEN BYTE (FOR CHECKSUM) BNE 90$ ;;;IF NE ODD (HIGH ORDER CHECKSUM BYTE) MOVB RDAT(R4),CKSM2(R4) ;;;LOW ORDER CHECKSUM BYTE BR 100$ 90$: MOVB RDAT(R4),CKSM2+1(R4) ;;;HIGH ORDER CHECKSUM BYTE CALL CHKPT 100$: DECB FLAG(R4) ;;;DECREMENT DATA COUNT BR 160$ RTWO: MOVB RDAT(R4),CKSM2(R4) ;;;RECEIVE LOW ORDER CHECKSUM BR 160$ RTHR: MOVB RDAT(R4),CKSM2+1(R4) ;;;RECEIVE HIGH ORDER CMP CKSM1(R4),CKSM2(R4) ;;;ARE CHECKSUMS CORRECT? BNE 40$ 160$: JMP RMSG ;;;READ FIRST BYTE OF NEXT PACKET .DSABL LSB ;+ ; TIMEOUT IS ENTERED WHEN THE DL11 DOES NOT RESPOND WITHIN ; A CERTAIN PRESET TIME TO THE SUBROUTINES SMSG AND RMSG ; SETTING INTERRUPT ENABLE AND ISSUING A RETURN. THIS ; INDICATES A HARDWARE FAILURE OF THE DL11 OR TU58. ;- DDOUT: BIC #,@DBUF(R3) ;;;CLEAR INTERRUPT ENABLE MOV R3,R4 ;COPY CONTROLLER INDEX TSTB FLAG+1(R4) ; RECEIVE TIMEOUT ? BNE 2$ ; YES 1$: SUB #DDXBF-DDXCS,DBUF(R4); POINT TO RECEIVE BUFFER BR 6$ ; 2$: BIT #TRNACK,FLGTYP(R4);IN PROCESS OF ACK CHAR ? BEQ 4$ ; NO - JUST A RECEIVE TIMEOUT BIC #TRNACK,FLGTYP(R4);CLEAR MUST ACK CHAR FLAG BR 1$ ; 4$: ADD #DDRBF-DDRCS,DBUF(R4); POINT TO RECEIVE BUFFER 6$: CALL LOGTMO ; LOG TIMEOUT ERROR MOV R4,R3 ; COPY CONTROLLER INDEX ADD #DDXBF-DDRBF,DBUF(R4); POINT TO TRANSMITTER BUFFER DECB U.CW2+1(R5) ;DECREMENT RETRY COUNT BLE 10$ ;IF LE, NO RETRIES LEFT JMP TINIT ;RE-INIT AND RETRY 10$: CLR CKSM2(R3) ;CLEAR BYTE TRANSFERRED COUNT MOV #IE.TMO&377,R0 ;TIMEOUT ERROR JMP ENDOP .END